package com.billdimmick.merkabah;

import java.util.Map;
import java.util.UUID;

import junit.framework.Assert;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestSQSManager extends TestSQSManagerBase{

	protected static final Log log=LogFactory.getLog(TestSQSManager.class);
	
	protected MockSQSManager manager;
	
	@Before
	public void setUp() throws Exception {
		this.manager=new MockSQSManager();
		super.manager=this.manager;
	}

	@After
	public void tearDown() throws Exception {
	}
	
	@Test
	public void testListQueuesSenderFailure() throws SQSException {
		final String code="SomeError";
		final String message="This is some message.";
		final String requestId=UUID.randomUUID().toString();
		manager.returnError("Sender", code, message, requestId);
		try {
			manager.listQueues();
			Assert.fail("List did not throw SenderSQSException ");
		} catch (SenderSQSException e) {
			Assert.assertEquals(code, e.getExceptionCode());
			Assert.assertEquals(message, e.getMessage());
			Assert.assertEquals(requestId, e.getRequestId());
		}
	}

	@Test
	public void testListQueuesClientSideFailure() throws SQSException {
		manager.createCommunicationException();
		try {
			manager.listQueues();
			Assert.fail("Create queue did not throw ClientSideSQSException ");
		} catch (ClientSideSQSException e) {
		}
	}

	
	@Test
	public void testCreateQueueSenderFailureWithDefaultTimeout() throws SQSException {
		final String code="SomeError";
		final String message="This is some message.";
		final String requestId=UUID.randomUUID().toString();
		manager.returnError("Sender", code, message, requestId);
		try {
			manager.createQueue("queue");
			Assert.fail("Create queue did not throw SenderSQSException ");
		} catch (SenderSQSException e) {
			Assert.assertEquals(code, e.getExceptionCode());
			Assert.assertEquals(message, e.getMessage());
			Assert.assertEquals(requestId, e.getRequestId());
		}
	}


	@Test
	public void testCreateQueueClientSideFailure() throws SQSException {
		manager.createCommunicationException();
		try {
			manager.createQueue("queue");
			Assert.fail("Create queue did not throw SenderSQSException ");
		} catch (ClientSideSQSException e) {
		}
	}

	@Test
	public void testCreateQueueReceiverFailureWithDefaultTimeout() throws SQSException {
		final String code="SomeError";
		final String message="This is some message.";
		final String requestId=UUID.randomUUID().toString();
		manager.returnError("Receiver", code, message, requestId);
		try {
			manager.createQueue("queue");
			Assert.fail("Create queue did not throw ReceiverSQSException ");
		} catch (ReceiverSQSException e) {
			Assert.assertEquals(code, e.getExceptionCode());
			Assert.assertEquals(message, e.getMessage());
			Assert.assertEquals(requestId, e.getRequestId());
		}
	}

	@Test
	public void testCreateQueueSenderFailureWithTimeout() throws SQSException {
		final String code="SomeError";
		final String message="This is some message.";
		final String requestId=UUID.randomUUID().toString();
		manager.returnError("Sender", code, message, requestId);
		try {
			manager.createQueue("queue", 15);
			Assert.fail("Create queue did not throw SenderSQSException ");
		} catch (SenderSQSException e) {
			Assert.assertEquals(code, e.getExceptionCode());
			Assert.assertEquals(message, e.getMessage());
			Assert.assertEquals(requestId, e.getRequestId());
		}
	}

	@Test
	public void testCreateQueueReceiverFailureWithTimeout() throws SQSException {
		final String code="SomeError";
		final String message="This is some message.";
		final String requestId=UUID.randomUUID().toString();
		manager.returnError("Receiver", code, message, requestId);
		try {
			manager.createQueue("queue", 15);
			Assert.fail("Create queue did not throw ReceiverSQSException ");
		} catch (ReceiverSQSException e) {
			Assert.assertEquals(code, e.getExceptionCode());
			Assert.assertEquals(message, e.getMessage());
			Assert.assertEquals(requestId, e.getRequestId());
		}
	}

	@Test
	public void testCreateQueueReceiverFailureNegativeTimeout() throws SQSException {
		try {
			manager.createQueue("queue", -1);
			Assert.fail("Create queue did not throw IllegalArgumentException");
		} catch (IllegalArgumentException e) {
		}
	}

	@Test
	public void testCreateQueueReceiverFailureNullQueueName() throws SQSException {
		try {
			manager.createQueue(null, 1);
			Assert.fail("Create queue did not throw IllegalArgumentException");
		} catch (IllegalArgumentException e) {
		}
		try {
			manager.createQueue(null);
			Assert.fail("Create queue did not throw IllegalArgumentException");
		} catch (IllegalArgumentException e) {
		}
	}

	@Test
	public void testCreateQueueReceiverFailureEmptyQueueName() throws SQSException {
		try {
			manager.createQueue("", 1);
			Assert.fail("Create queue did not throw IllegalArgumentException");
		} catch (IllegalArgumentException e) {
		}
		try {
			manager.createQueue("");
			Assert.fail("Create queue did not throw IllegalArgumentException");
		} catch (IllegalArgumentException e) {
		}
	}

	@Test
	public void testDeleteQueueReceiverFailureNullQueueName() throws SQSException {
		try {
			manager.deleteQueue(null);
			Assert.fail("Delete Queue did not throw IllegalArgumentException");
		} catch (IllegalArgumentException e) {
		}
	}

	@Test
	public void testDeleteQueueReceiverFailureEmptyQueueName() throws SQSException {
		try {
			manager.deleteQueue("");
			Assert.fail("Delete Queue did not throw IllegalArgumentException");
		} catch (IllegalArgumentException e) {
		}
	}

	@Test
	public void testDeleteQueueSenderFailure() throws SQSException {
		final String code="SomeError";
		final String message="This is some message.";
		final String requestId=UUID.randomUUID().toString();
		manager.returnError("Sender", code, message, requestId);
		try {
			manager.deleteQueue("queue");
			Assert.fail("Delete queue did not throw SenderSQSException ");
		} catch (SenderSQSException e) {
			Assert.assertEquals(code, e.getExceptionCode());
			Assert.assertEquals(message, e.getMessage());
			Assert.assertEquals(requestId, e.getRequestId());
		}
	}

	@Test
	public void testDeleteQueueReceiverFailure() throws SQSException {
		final String code="SomeError";
		final String message="This is some message.";
		final String requestId=UUID.randomUUID().toString();
		manager.returnError("Receiver", code, message, requestId);
		try {
			manager.deleteQueue("queue");
			Assert.fail("Delete queue did not throw ReceiverSQSException");
		} catch (ReceiverSQSException e) {
			Assert.assertEquals(code, e.getExceptionCode());
			Assert.assertEquals(message, e.getMessage());
			Assert.assertEquals(requestId, e.getRequestId());
		}
	}
		
	@Test
	public void testSendSenderFailure() throws SQSException {
		final String code="SomeError";
		final String message="This is some message.";
		final String requestId=UUID.randomUUID().toString();
		manager.createQueue("queue");
		manager.returnError("Sender", code, message, requestId);
		try {
			manager.send("queue", "message");
			Assert.fail("Send did not throw SenderSQSException ");
		} catch (SenderSQSException e) {
			Assert.assertEquals(code, e.getExceptionCode());
			Assert.assertEquals(message, e.getMessage());
			Assert.assertEquals(requestId, e.getRequestId());
		}		
	}

	@Test
	public void testSendReceiverFailure() throws SQSException {
		final String code="SomeError";
		final String message="This is some message.";
		final String requestId=UUID.randomUUID().toString();
		manager.createQueue("queue");
		manager.returnError("Receiver", code, message, requestId);
		try {
			manager.send("queue", "message");
			Assert.fail("Send did not throw ReceiverSQSException");
		} catch (ReceiverSQSException e) {
			Assert.assertEquals(code, e.getExceptionCode());
			Assert.assertEquals(message, e.getMessage());
			Assert.assertEquals(requestId, e.getRequestId());
		}		
	}

	@Test
	public void testSendNullQueue() throws SQSException {
		try {
			manager.send(null, "yo");
			Assert.fail("Send with null queue did not throw IllegalArgumentException");
		} catch (IllegalArgumentException e) {
		}
	}

	@Test
	public void testSenderNonexistenstQueue() throws SQSException {
		try {
			manager.send("bad", "yo");
			Assert.fail("Send with non-existent queue did not throw SenderSQSException");
		} catch (SenderSQSException e) {
		}
	}

	@Test
	public void testSenderNullBody() throws SQSException {
		try {
			manager.send("queue", null);
			Assert.fail("Send with null body did not throw IllegalArgumentException");
		} catch (IllegalArgumentException e) {
		}
	}

	@Test
	public void testReceiveWithTimeout() throws SQSException {
		manager.createQueue("queue");
		manager.send("queue", "hello");
		manager.receive("queue", 2, 1);
		Map<String, String> parameters=manager.getRequestQueryParameters();
		Assert.assertEquals("1", parameters.get("VisibilityTimeout"));
		Assert.assertEquals("2", parameters.get("MaxNumberOfMessages"));
	}
}


